home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / estra.lha / estra / src / Grammar.mi < prev    next >
Text File  |  1992-08-18  |  12KB  |  502 lines

  1. (* $Id: Grammar.mi,v 2.1 1992/08/07 15:47:31 grosch rel $ *)
  2.  
  3. IMPLEMENTATION MODULE Grammar;
  4.  
  5. FROM    Convert        IMPORT  IdToAdr, AdrToId;
  6.  
  7. FROM    Heap        IMPORT    Alloc;
  8.  
  9. FROM    DynArray    IMPORT    MakeArray, ReleaseArray;
  10.  
  11. FROM    Idents        IMPORT    tIdent;
  12.  
  13. FROM    Lists        IMPORT    tList, MakeList, Append, Head, Tail;
  14.  
  15. FROM    Scanner        IMPORT    NoIdent, NoValue, MaxIdent;
  16.  
  17. FROM    Stack        IMPORT    tStack, MakeStack, ReleaseStack, Push,
  18.                 Pop, Depth;
  19.  
  20. FROM    Sets        IMPORT    tSet, MakeSet, ReleaseSet, Assign, Include,
  21.                 Exclude, Union, Extract, IsEmpty, IsElement,
  22.                 Card, Minimum, Maximum, IsSubset, Complement,
  23.                 Intersection;
  24.  
  25. FROM    SYSTEM        IMPORT    TSIZE, ADDRESS;
  26.  
  27. FROM    Types        IMPORT    tType, Type, AllNodes, AllClasses;
  28.  
  29.  
  30. (* GRAM_ *)
  31. FROM    Errors        IMPORT    ERROR;
  32. FROM    Info        IMPORT    WriteIdentSet;
  33. FROM    Idents        IMPORT    WriteIdent;
  34. FROM    IO        IMPORT    tFile, StdOutput;
  35. FROM    StdIO        IMPORT    WriteI, WriteS, WriteNl, WriteN;
  36. IMPORT    IO;
  37. (* _GRAM *)
  38.  
  39. CONST
  40.  
  41.   NoArity = -1;
  42.   infinite = 100000;
  43.  
  44.  
  45. TYPE
  46.   tIndexes = POINTER TO ARRAY [0..1000] OF INTEGER;
  47.  
  48.   tClass =
  49.     RECORD
  50.       superclass: tIdent;
  51.       nodes: tSet;
  52.       directsubclasses: tSet;
  53.       subclasses: tSet;
  54.       layouts: tList;
  55.     END;
  56.  
  57.   tNode =
  58.     RECORD
  59.       mainclass: tIdent;
  60.       nodeident: tIdent;
  61.       arity: INTEGER;
  62.       sonnames: tSons;
  63.       classes: tSet;
  64.       layouts: tList;
  65.       numbers: tSet;
  66.     END;
  67.  
  68.   tClassOrNode =
  69.     POINTER TO RECORD
  70.       CASE :tType OF
  71.       | cClass: Class: tClass;
  72.       | cNode:  Node:  tNode;
  73.       END;
  74.     END;
  75.  
  76. VAR
  77.   TG : POINTER TO ARRAY [0..1000] OF tClassOrNode;
  78.   vMaxArity: INTEGER;
  79.  
  80.  
  81. PROCEDURE BeginGrammar;
  82.   VAR size: LONGINT; id: tIdent;
  83.   BEGIN
  84.     (* GRAM1_   
  85.     WriteS ('BeginGrammar'); WriteNl;
  86.        _GRAM1 *)
  87.     size := MaxIdent + 1;
  88.     MakeArray (TG, size, TSIZE (tClassOrNode));
  89.     FOR id := 0 TO MaxIdent DO
  90.       CASE Type (id) OF
  91.       | cClass: 
  92.       TG^[id] := Alloc (TSIZE (tClass));
  93.       WITH TG^[id]^.Class DO
  94.         (* GRAM1_   
  95.         WriteS ('Class: '); WriteI (id,1); WriteNl;
  96.            _GRAM1 *)
  97.         superclass := NoIdent;
  98.         MakeSet (nodes, MaxIdent);
  99.         MakeSet (directsubclasses, MaxIdent);
  100.         MakeSet (subclasses, MaxIdent);
  101.         MakeList (layouts);
  102.       END;
  103.       | cNode:
  104.         (* GRAM1_   
  105.         WriteS ('Node: '); WriteI (id,1); WriteNl;
  106.            _GRAM1 *)
  107.       TG^[id] := Alloc (TSIZE (tNode));
  108.       WITH TG^[id]^.Node DO
  109.         mainclass := NoIdent;
  110.         nodeident := id;
  111.         arity := NoArity;
  112.         sonnames := NIL;
  113.         MakeSet (classes, MaxIdent);
  114.         MakeList (layouts);
  115.       END;
  116.       ELSE
  117.     TG^[id] := NIL;
  118.       END;
  119.     END;
  120.   END BeginGrammar;
  121.  
  122.  
  123. PROCEDURE SetSuperClass        (class, super: tIdent);
  124.   BEGIN
  125.     (* GRAM_ *)
  126.   IF Type (class) # cClass THEN ERROR ('SetSuperClass: class is no class'); END;
  127.   IF Type (super) # cClass THEN ERROR ('SetSuperClass: super is no class'); END;
  128.     (* _GRAM *)
  129.     TG^[class]^.Class.superclass := super;
  130.     Include (TG^[super]^.Class.directsubclasses, class);
  131.   END SetSuperClass;
  132.  
  133.  
  134. PROCEDURE Connect        (node, class: tIdent);
  135.   BEGIN
  136.     (* GRAM1_   
  137.     IF Type (node) # cNode THEN ERROR ('Connect: no node'); END;
  138.     IF Type (class) # cClass THEN ERROR ('Connect: no class'); END;
  139.     WriteS ('connect');
  140.     WriteS ('  node: '); WriteI (node,1);
  141.     WriteS ('  class: '); WriteI (class,1); WriteNl;
  142.        _GRAM1 *)
  143.     Include (TG^[class]^.Class.nodes, node);
  144.     Include (TG^[node]^.Node.classes, class);
  145.   END Connect;
  146.  
  147.  
  148. PROCEDURE CompleteSubclasses;
  149.   BEGIN
  150.     Digraph;
  151.   END CompleteSubclasses;
  152.  
  153. PROCEDURE Digraph;
  154.   VAR
  155.     S: tStack;
  156.     N: tIndexes;
  157.     x: tIdent;
  158.     size: LONGINT;
  159.  
  160.   BEGIN
  161.     MakeStack (S);
  162.     size := MaxIdent + 1;
  163.     MakeArray (N, size, TSIZE (INTEGER));
  164.     
  165.     FOR x := 0 TO MaxIdent DO
  166.       N^[x] := 0;
  167.     END;
  168.  
  169.     FOR x := 0 TO MaxIdent DO
  170.       IF (N^[x] = 0) & (Type (x) = cClass) THEN
  171.     Traverse (x, N, S);
  172.       END;
  173.     END;
  174.  
  175.     ReleaseArray (N, size, TSIZE (INTEGER));
  176.     ReleaseStack (S);
  177.   END Digraph;
  178.  
  179.  
  180. PROCEDURE Traverse (x: tIdent; N: tIndexes; VAR S: tStack);
  181.   VAR
  182.     d: INTEGER;
  183.     X: tSet;
  184.     y: tIdent;
  185.   BEGIN
  186.     MakeSet (X, MaxIdent);
  187.     Push (S, IdToAdr (x));
  188.     d := Depth (S);
  189.     N^[x] := d;
  190.     Assign (TG^[x]^.Class.subclasses, TG^[x]^.Class.directsubclasses);
  191.     DirectSubclasses (x, X);
  192.     WHILE NOT IsEmpty (X) DO
  193.       y := Extract (X);
  194.       IF N^[y] = 0 THEN
  195.     Traverse (y, N, S);
  196.       END;
  197.       IF N^[x] > N^[y] THEN
  198.     N^[x] := N^[y];
  199.       END;
  200.       Union (TG^[x]^.Class.subclasses, TG^[y]^.Class.subclasses);
  201.     END;
  202.     IF N^[x] = d THEN
  203.       REPEAT
  204.     y := AdrToId (Pop (S));
  205.     N^[y] := infinite;
  206.     IF x # y THEN
  207.       Assign (TG^[y]^.Class.subclasses, TG^[x]^.Class.subclasses);
  208.     END;
  209.       UNTIL y = x
  210.     END;
  211.     ReleaseSet (X);
  212.   END Traverse;
  213.  
  214.  
  215. PROCEDURE FixMainClasses;
  216.   VAR nodes: tSet;
  217.   BEGIN
  218.     MakeSet (nodes, MaxIdent);
  219.     AllNodes (nodes);
  220.     WHILE NOT IsEmpty (nodes) DO
  221.       FixMainClass (Extract (nodes));
  222.     END;
  223.     ReleaseSet (nodes);
  224.   END FixMainClasses;
  225.  
  226. PROCEDURE FixMainClass (node: tIdent);
  227.   VAR card: INTEGER; cl: tIdent; mcl: tSet;
  228.   BEGIN
  229.     (* GRAM_ *)
  230.     IF Type (node) # cNode THEN ERROR ('FixMainClass: no node'); END;
  231.     (* _GRAM *)
  232.     WITH TG^[node]^.Node DO
  233.       card := Card (classes);
  234.       IF card = 0 THEN
  235.     (* no class at all *)
  236.       ELSIF card = 1 THEN
  237.     mainclass := Minimum (classes);
  238.       ELSE
  239.     MakeSet (mcl, MaxIdent);    (* posible main classes *)
  240.     FOR cl := Minimum (classes) TO Maximum (classes) DO
  241.       IF IsElement (cl, classes) THEN
  242.         Exclude (classes, cl);
  243.         IF IsSubset (classes, TG^[cl]^.Class.subclasses) THEN
  244.           Include (mcl, cl);
  245.         END;
  246.         Include (classes, cl);
  247.       END;
  248.     END;
  249.     IF Card (mcl) = 1 THEN
  250.       mainclass := Minimum (mcl);    (* else there is no uniq main class *)
  251.     END;
  252.     ReleaseSet (mcl);
  253.       END;
  254.     END;
  255.   END FixMainClass;
  256.  
  257.  
  258. PROCEDURE NodesOfClass        (class: tIdent; VAR nodes: tSet);
  259.   BEGIN
  260.     (* GRAM_ *)
  261.     IF Type (class) # cClass THEN ERROR ('NodesOfClass: no class'); END;
  262.     (* _GRAM *)
  263.     Assign (nodes, TG^[class]^.Class.nodes);
  264.   END NodesOfClass;
  265.  
  266.  
  267. PROCEDURE ClassesOfNode        (node: tIdent; VAR classes: tSet);
  268.   BEGIN
  269.     (* GRAM_ *)
  270.     IF Type (node) # cNode THEN ERROR ('ClassesOfNode: no node'); END;
  271.     (* _GRAM *)
  272.     Assign (classes, TG^[node]^.Node.classes);
  273.   END ClassesOfNode;
  274.  
  275.  
  276. PROCEDURE SuperClass        (class: tIdent): tIdent;
  277.   BEGIN
  278.     (* GRAM_ *)
  279.     IF Type (class) # cClass THEN ERROR ('SuperClass: no class'); END;
  280.     (* _GRAM *)
  281.     RETURN TG^[class]^.Class.superclass;
  282.   END SuperClass;
  283.  
  284.  
  285. PROCEDURE IsSubclass        (class, super: tIdent): BOOLEAN;
  286.   BEGIN
  287.     (* GRAM_ *)
  288.     IF Type (class) # cClass THEN ERROR ('IsSubClass: class is no class'); END;
  289.     IF Type (super) # cClass THEN ERROR ('IsSubClass: super is no class'); END;
  290.     (* _GRAM *)
  291.     RETURN IsElement (class, TG^[super]^.Class.subclasses);
  292.   END IsSubclass;
  293.  
  294.  
  295. PROCEDURE DirectSubclasses    (class: tIdent; VAR sub: tSet);
  296.   BEGIN
  297.     (* GRAM_ *)
  298.     IF Type (class) # cClass THEN ERROR ('DirectSubClass: no class'); END;
  299.     (* _GRAM *)
  300.     Assign (sub, TG^[class]^.Class.directsubclasses);
  301.   END DirectSubclasses;
  302.  
  303.  
  304. PROCEDURE Subclasses    (class: tIdent; VAR sub: tSet);
  305.   BEGIN
  306.     (* GRAM_ *)
  307.     IF Type (class) # cClass THEN ERROR ('DirectSubClass: no class'); END;
  308.     (* _GRAM *)
  309.     Assign (sub, TG^[class]^.Class.subclasses);
  310.   END Subclasses;
  311.  
  312.  
  313. PROCEDURE MainClass        (node: tIdent): tIdent;
  314.   BEGIN
  315.     RETURN TG^[node]^.Node.mainclass;
  316.   END MainClass;
  317.  
  318.  
  319.  
  320. PROCEDURE SetNodeIdent        (node, id: tIdent);
  321.   BEGIN
  322.     TG^[node]^.Node.nodeident := id;
  323.   END SetNodeIdent;
  324.  
  325.  
  326. PROCEDURE SetArity        (node: tIdent; ari: INTEGER);
  327.   VAR pos: INTEGER; size: LONGINT;
  328.   BEGIN
  329.     (* GRAM1_   
  330.     IF Type (node) # cNode THEN ERROR ('SetArity: no node'); END;
  331.     WriteS ('Arity ('); WriteIdent (StdOutput, node);
  332.     WriteS (') = '); WriteI (ari, 1); WriteNl;
  333.        _GRAM1 *)
  334.     WITH TG^[node]^.Node DO
  335.       arity := ari;
  336.       size := ari + 1;
  337.       MakeArray (sonnames, size, TSIZE (tSon));
  338.       FOR pos := 0 TO arity DO
  339.     sonnames^[pos] := NoIdent;
  340.       END;
  341.     END;
  342.     IF ari > vMaxArity THEN vMaxArity := ari END;
  343.   END SetArity;
  344.  
  345.  
  346. PROCEDURE SetSonName        (node: tIdent; pos: INTEGER; name: tIdent);
  347.   BEGIN
  348.     TG^[node]^.Node.sonnames^[pos] := name;
  349.   END SetSonName;
  350.  
  351.  
  352. PROCEDURE CreateLayout        (no, cl: tIdent): tLayout;
  353.   VAR layout: tLayout; size: LONGINT; arity, pos: INTEGER;
  354.   BEGIN
  355.     (* GRAM_ *)
  356.     IF Type (no) # cNode THEN ERROR ('CreateLayout: no node'); END;
  357.     IF Type (cl) # cClass THEN ERROR ('CreateLayout: no class'); END;
  358.     (* _GRAM *)
  359.     arity := Arity (no);
  360.     layout := Alloc (TSIZE (tLayoutRec));
  361.     WITH layout^ DO
  362.       node := no;
  363.       class := cl;
  364.       size := arity + 1;
  365.       MakeArray (sons, size, TSIZE (tSon));
  366.       FOR pos := 0 TO arity DO
  367.     sons^[pos] := NoIdent;
  368.       END;
  369.     END;
  370.     Append (TG^[no]^.Node.layouts, layout);
  371.     Append (TG^[cl]^.Class.layouts, layout);
  372.     RETURN layout;
  373.   END CreateLayout;
  374.  
  375.  
  376. PROCEDURE SetSonClass        (layout: tLayout; pos: INTEGER; class: tIdent);
  377.   BEGIN
  378.     layout^.sons^[pos] := class;
  379.   END SetSonClass;
  380.  
  381.  
  382. PROCEDURE NodeIdent        (node: tIdent): tIdent;
  383.   BEGIN
  384.     RETURN TG^[node]^.Node.nodeident;
  385.   END NodeIdent;
  386.  
  387.  
  388. PROCEDURE Arity            (node: tIdent): INTEGER;
  389.   BEGIN
  390.     RETURN TG^[node]^.Node.arity;
  391.   END Arity;
  392.  
  393.  
  394. PROCEDURE SonName        (node: tIdent; pos: INTEGER): tIdent;
  395.   BEGIN
  396.     RETURN TG^[node]^.Node.sonnames^[pos];
  397.   END SonName;
  398.  
  399.  
  400. PROCEDURE Layout        (node, class: tIdent): tLayout;
  401.   VAR layouts: tList; layout: tLayout;
  402.   BEGIN
  403.     (* GRAM_ *)
  404.     IF Type (node) # cNode THEN ERROR ('Layout: no node'); END;
  405.     IF Type (class) # cClass THEN ERROR ('Layout: no class'); END;
  406.     (* _GRAM *)
  407.     layouts := TG^[node]^.Node.layouts;
  408.     LOOP
  409.       layout := Head (layouts);
  410.       IF layout^.class = class THEN RETURN layout END;
  411.       Tail (layouts);
  412.     END;
  413.   END Layout;
  414.  
  415.  
  416. PROCEDURE SonClass        (layout: tLayout; pos: INTEGER): tIdent;
  417.   BEGIN
  418.     RETURN layout^.sons^[pos];
  419.   END SonClass;
  420.  
  421.  
  422. PROCEDURE MakePatNumbers (size: INTEGER);
  423.   VAR nodes: tSet;
  424.   BEGIN
  425.     MakeSet (nodes, MaxIdent);
  426.     AllNodes (nodes);
  427.     WHILE NOT IsEmpty (nodes) DO
  428.       MakeSet (TG^[Extract (nodes)]^.Node.numbers, size);
  429.     END;
  430.     ReleaseSet (nodes);
  431.   END MakePatNumbers;
  432.  
  433. PROCEDURE AddPatNumber (node: tIdent; number: INTEGER);
  434.   BEGIN
  435.     Include (TG^[node]^.Node.numbers, number);
  436.   END AddPatNumber;
  437.  
  438. PROCEDURE PatsOfNode (node: tIdent; VAR numbers: tSet);
  439.   BEGIN
  440.     Assign (numbers, TG^[node]^.Node.numbers);
  441.   END PatsOfNode;
  442.  
  443. PROCEDURE MaxArity (): INTEGER;
  444.   BEGIN
  445.     RETURN vMaxArity;
  446.   END MaxArity;
  447.  
  448.  
  449. (* GRAM_ *)
  450. PROCEDURE WriteGrammar        (f: tFile);
  451.   VAR id: tIdent;
  452.   BEGIN
  453.     FOR id := 1 TO MaxIdent DO
  454.       CASE Type (id) OF
  455.       | cClass:
  456.       WITH TG^[id]^.Class DO
  457.         IO.WriteS (f, 'class:                ');
  458.         WriteIdent (f, id);
  459.         IO.WriteNl (f);
  460.         IO.WriteS (f, '  super class:        ');
  461.         WriteIdent (f, superclass);
  462.         IO.WriteNl (f);
  463.         IO.WriteS (f, '  nodes:              ');
  464.         WriteIdentSet (f, nodes);
  465.         IO.WriteNl (f);
  466.         IO.WriteS (f, '  direct sub classes: ');
  467.         WriteIdentSet (f, directsubclasses);
  468.         IO.WriteNl (f);
  469.         IO.WriteS (f, '  sub classes:        ');
  470.         WriteIdentSet (f, subclasses);
  471.         IO.WriteNl (f);
  472.       END;
  473.       | cNode:
  474.       WITH TG^[id]^.Node DO
  475.         IO.WriteS (f, 'node:                 ');
  476.         WriteIdent (f, id);
  477.         IO.WriteNl (f);
  478.         IO.WriteS (f, '  main class:         ');
  479.         WriteIdent (f, mainclass);
  480.         IO.WriteNl (f);
  481.         IO.WriteS (f, '  node ident:         ');
  482.         WriteIdent (f, nodeident);
  483.         IO.WriteNl (f);
  484.         IO.WriteS (f, '  arity:              ');
  485.         IO.WriteI (f, arity, 1);
  486.         IO.WriteNl (f);
  487.         IO.WriteS (f, '  classes:            ');
  488.         WriteIdentSet (f, classes);
  489.         IO.WriteNl (f);
  490.       END;
  491.       ELSE
  492.       END;
  493.     END;
  494.   END WriteGrammar;
  495. (* _GRAM *)
  496.  
  497.  
  498.  
  499. BEGIN
  500.   vMaxArity := 0;
  501. END Grammar.
  502.